package cn.jinjimi.app.main.adapter.recycler;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import cn.jinjimi.app.R;
import cn.jinjimi.app.entity.Notice;
import cn.jinjimi.app.interfaces.IGridLayoutAdapter;
import cn.jinjimi.app.main.widget.FrescoImageView.FrescoImageView;
import cn.jinjimi.base.util.TimeUtils;
import cn.jinjimi.domain.data.dto.CommentList;
import cn.jinjimi.domain.entity.ProductList;
import cn.jinjimi.domain.entity.Comment;
import cn.jinjimi.domain.entity.Product;
import cn.jinjimi.framework.router.RouterHelper;


public class HomeAdapter extends MyBaseRecyclerAdapter<Object, HomeAdapter.BaseViewHolder> implements IGridLayoutAdapter {
    private static final int TYPE_SECTION_CATE_TITLE = 0x1;
    private static final int TYPE_SECTION_CATE_PRODUCT = 0x2;
    private static final int TYPE_SECTION_CATE_COMMENT = 0x3;
    private static final int TYPE_SECTION_CATE_RECOMMEND = 0x4;

    private static final int TYPE_EMPTY = 0x0;
    private static final int POSITION_START = 0;

    private List<Section<Product>> mCateProductSet = new ArrayList<>();
    private List<Section<Comment>> mCommentSet = new ArrayList<>();
    private List<Section<Product>> mGoodsSet = new ArrayList<>();
    private List<Section<Notice>> mRecommends = new ArrayList<>();
    private int mCateProductSetOffset;
    private int mGoodsSetOffset;
    private int mCommentSetOffset;
    private int mRecommedsSetOffset;
    private int mTotalCount;

    public HomeAdapter() {

    }

    public void setRecommends(List<Notice> data) {
        if (data != null) {
            mRecommends = parseRecommedsData(data);
            updateOffsetPosition();
            notifyDataSetChanged();
        }
    }

    public void setCateData(List<ProductList> data) {
        if (data != null) {
            mCateProductSet = parseCateData(data);
            updateOffsetPosition();
            notifyDataSetChanged();
        }
    }

    public void setCommentData(CommentList data) {
        if (data != null) {
            mCommentSet = new ArrayList<>();
            mCommentSet.add(new Section<>(data.label, data.img, data.link, data.comments));
            updateOffsetPosition();
            notifyDataSetChanged();
        }
    }

    public void setGoodsData(ProductList data) {
        if (data != null) {
            mGoodsSet = new ArrayList<>();
            mGoodsSet.add(new Section<>(data.label, data.img, data.link, data.products));
            updateOffsetPosition();
            notifyDataSetChanged();
        }
    }

    private void updateOffsetPosition() {
        int count = POSITION_START;

        for (Section sec : mRecommends) {
            count += sec.getItemCount() + 1;
        }
        mRecommedsSetOffset = count;

        for (Section sec : mCateProductSet) {
            count += sec.getItemCount() + 1;
        }
        mCateProductSetOffset = count;

        for (Section sec : mGoodsSet) {
            count += sec.getItemCount() + 1;
        }
        mGoodsSetOffset = count;

        for (Section sec : mCommentSet) {
            count += sec.getItemCount() + 1;
        }
        mCommentSetOffset = count;

        mTotalCount = count;
    }

    private List<Section<Product>> parseCateData(List<ProductList> data) {
        List<Section<Product>> sections = new ArrayList<>();
        for (ProductList c : data) {
            if (c.products != null) {
                sections.add(new Section<>(c.label, c.img, c.link, c.products));
            }
        }
        return sections;
    }

    private List<Section<Notice>> parseRecommedsData(List<Notice> data) {
        List<Section<Notice>> sections = new ArrayList<>();
        sections.add(new Section<>("小金推荐", "", "", data));
        return sections;
    }

    @Override
    public int getItemCount() {
        return mTotalCount;
    }

    @Override
    public int getItemViewType(int position) {
        if (position >= POSITION_START && position < mRecommedsSetOffset) {
            return getRecommendViewType(POSITION_START, position);
        } else if (position>= mRecommedsSetOffset && position < mCateProductSetOffset) {
            return getCateProductViewType(mRecommedsSetOffset, position);
        } else if (position >= mCateProductSetOffset && position < mGoodsSetOffset) {
            return getGoodsProductViewType(mCateProductSetOffset, position);
        } else if (position >= mGoodsSetOffset && position < mCommentSetOffset) {
            return getCommentViewType(mGoodsSetOffset, position);
        }
        return TYPE_EMPTY;
    }

    public Object getItemByType(int type, int position) {
        if (TYPE_SECTION_CATE_TITLE == type) {
            return getSection(position);
        } else if (TYPE_SECTION_CATE_PRODUCT == type
            || TYPE_SECTION_CATE_COMMENT == type
            || TYPE_SECTION_CATE_RECOMMEND == type) {
            return getProduct(position);
        }
        return null;
    }

    private Notice getRecommend(int offset, int position){
        for (Section<Notice> sec : mRecommends) {
            if (position > offset && position <= offset + sec.getItemCount()) {
                return sec.getItem(position - offset - 1);
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Product getCateProduct(int offset, int position) {
        for (Section<Product> sec : mCateProductSet) {
            if (position > offset && position <= offset + sec.getItemCount()) {
                return sec.getItem(position - offset - 1);
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Product getCoodsProduct(int offset, int position) {
        for (Section<Product> sec : mGoodsSet) {
            if (position > offset && position <= offset + sec.getItemCount()) {
                return sec.getItem(position - offset - 1);
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Comment getComment(int offset, int position) {
        for (Section<Comment> sec : mCommentSet) {
            if (position > offset && position <= offset + sec.getItemCount()) {
                return sec.getItem(position - offset - 1);
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Object getProduct(int position) {
        if (position >= POSITION_START && position < mRecommedsSetOffset) {
            return getRecommend(POSITION_START, position);
        } else if (position >= mRecommedsSetOffset && position < mCateProductSetOffset) {
            return getCateProduct(mRecommedsSetOffset, position);
        } else if (position >= mCateProductSetOffset && position < mGoodsSetOffset) {
            return getCoodsProduct(mCateProductSetOffset, position);
        } else if (position >= mGoodsSetOffset && position < mCommentSetOffset) {
            return getComment(mGoodsSetOffset, position);
        }
        return null;
    }

    private Section<Notice> getRecommentSection(int offset, int position) {
        for (Section<Notice> sec : mRecommends) {
            if (position == offset) {
                return sec;
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Section<Product> getCateSection(int offset, int position) {
        for (Section<Product> sec : mCateProductSet) {
            if (position == offset) {
                return sec;
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Section<Product> getGoodsSection(int offset, int position) {
        for (Section<Product> sec : mGoodsSet) {
            if (position == offset) {
                return sec;
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Section<Comment> getCommentSection(int offset, int position) {
        for (Section<Comment> sec : mCommentSet) {
            if (position == offset) {
                return sec;
            }
            offset += (sec.getItemCount() + 1);
        }
        return null;
    }

    private Section<?> getSection(int position) {
        if (position >= POSITION_START && position < mRecommedsSetOffset) {
            return getRecommentSection(POSITION_START, position);
        } else if (position >= mRecommedsSetOffset && position < mCateProductSetOffset) {
            return getCateSection(mRecommedsSetOffset, position);
        } else if (position >= mCateProductSetOffset && position < mGoodsSetOffset) {
            return getGoodsSection(mCateProductSetOffset, position);
        } else if (position >= mGoodsSetOffset && position < mCommentSetOffset) {
            return getCommentSection(mGoodsSetOffset, position);
        }
        return null;
    }

    private int getRecommendViewType(int offset, int position) {
        for (Section sec : mRecommends) {
            if (position == offset) {
                return TYPE_SECTION_CATE_TITLE;
            } else if (position > offset && position <= offset + sec.getItemCount()) {
                return TYPE_SECTION_CATE_RECOMMEND;
            }
            offset += (sec.getItemCount() + 1);
        }
        return TYPE_EMPTY;
    }

    private int getCateProductViewType(int offset, int position) {
        for (Section sec : mCateProductSet) {
            if (position == offset) {
                return TYPE_SECTION_CATE_TITLE;
            } else if (position > offset && position <= offset + sec.getItemCount()) {
                return TYPE_SECTION_CATE_PRODUCT;
            }
            offset += (sec.getItemCount() + 1);
        }
        return TYPE_EMPTY;
    }

    private int getGoodsProductViewType(int offset, int position) {
        for (Section sec : mGoodsSet) {
            if (position == offset) {
                return TYPE_SECTION_CATE_TITLE;
            } else if (position > offset && position <= offset + sec.getItemCount()) {
                return TYPE_SECTION_CATE_PRODUCT;
            }
            offset += (sec.getItemCount() + 1);
        }
        return TYPE_EMPTY;
    }

    private int getCommentViewType(int offset, int position) {
        for (Section sec : mCommentSet) {
            if (position == offset) {
                return TYPE_SECTION_CATE_TITLE;
            } else if (position > offset && position <= offset + sec.getItemCount()) {
                return TYPE_SECTION_CATE_COMMENT;
            }
            offset += (sec.getItemCount() + 1);
        }
        return TYPE_EMPTY;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView view) {
        super.onAttachedToRecyclerView(view);
        //view.addItemDecoration();
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_SECTION_CATE_TITLE:
                return new CateViewHolder(
                    LayoutInflater.from(parent.getContext()).inflate(R.layout.home_cate_item, parent, false)
                );
            case TYPE_SECTION_CATE_PRODUCT:
                return new ProductViewHolder(
                    LayoutInflater.from(parent.getContext()).inflate(R.layout.home_product_item, parent, false)
                );
            case TYPE_SECTION_CATE_COMMENT:
                return new CommentViewHolder(
                    LayoutInflater.from(parent.getContext()).inflate(R.layout.home_comment_item, parent, false)
                );
            case TYPE_SECTION_CATE_RECOMMEND:
                return new RecommendViewHolder(
                    LayoutInflater.from(parent.getContext()).inflate(R.layout.home_notice_item, parent, false)
                );
            case TYPE_EMPTY:
            default:
                return new EmptyViewHolder(new View(parent.getContext()));
        }
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
        int type = getItemViewType(position);
        switch (type) {
            case TYPE_SECTION_CATE_TITLE:
                ((CateViewHolder) holder).setData((Section<?>) getItemByType(type, position));
                break;
            case TYPE_SECTION_CATE_PRODUCT:
                ((ProductViewHolder) holder).setData((Product) getItemByType(type, position));
                break;
            case TYPE_SECTION_CATE_COMMENT:
                ((CommentViewHolder) holder).setData((Comment) getItemByType(type, position));
                break;
            case TYPE_SECTION_CATE_RECOMMEND:
                ((RecommendViewHolder) holder).setData((Notice) getItemByType(type, position));
                break;
            case TYPE_EMPTY:
            default:
                break;
        }

    }

    @Override
    protected Animator[] getAnimators(View view) {
        return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", 0f, 1f)};
    }


    @Override
    public int getSpanSize(int spanCount, int position) {
        int type = getItemViewType(position);
        if (type == TYPE_SECTION_CATE_TITLE) {
            return spanCount;
        } else if (type == TYPE_SECTION_CATE_PRODUCT || type == TYPE_SECTION_CATE_COMMENT) {
            return spanCount / 2;
        }
        return spanCount;
    }

    private class Section<T> {
        public String label;
        public List<T> items;
        public String link;
        public String img;

        public int getItemCount() {
            return items == null ? 0 : items.size();
        }

        public T getItem(int position) {
            return items.get(position);
        }

        public Section(String label, String img, String link, List<T> items) {
            this.items = items;
            this.label = label;
            this.img = img;
            this.link = link;
        }
    }

    public abstract class BaseViewHolder<T> extends MyBaseRecyclerAdapter.MyViewHolder {
        public BaseViewHolder(View itemView) {
            super(itemView);
        }
        public abstract void setData(T obj);
    }

    private class EmptyViewHolder extends BaseViewHolder<Object> {

        public EmptyViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void setData(Object obj) {

        }
    }

    private class ProductViewHolder extends BaseViewHolder<Product> {
        private TextView tvPrice;
        private RelativeLayout rlContent;
        private FrescoImageView imgIcon;
        private TextView tvTitle;
        private TextView tvDesc;

        public ProductViewHolder(View itemView) {
            super(itemView);
            initView(itemView);
        }

        private void initView(View itemView) {
            rlContent = (RelativeLayout) itemView.findViewById(R.id.rl_content);
            imgIcon = (FrescoImageView) itemView.findViewById(R.id.img_icon);
            tvTitle = (TextView) itemView.findViewById(R.id.tv_title);
            tvDesc = (TextView) itemView.findViewById(R.id.tv_desc);
            tvPrice = (TextView) itemView.findViewById(R.id.tv_price);
            rlContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    RouterHelper.toUrl(v.getContext(), (String) v.getTag());
                }
            });
        }

        @Override
        public void setData(final Product item) {
            if (item != null) {
                imgIcon.loadView(item.img);
                tvDesc.setText(item.desc);
                tvTitle.setText(item.title);
                rlContent.setTag(item.link);
                tvPrice.setText(String.format(Locale.CHINA, "¥%.2f", (float) item.salePrice / 100));
            }
        }

    }

    private class CateViewHolder extends BaseViewHolder<Section<?>> {

        private TextView mTitle;

        public CateViewHolder(View itemView) {
            super(itemView);
            initView(itemView);
        }

        private void initView(View itemView) {
            mTitle = (TextView) itemView.findViewById(R.id.cate_title);
            if (mTitle != null) {
                mTitle.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        RouterHelper.toUrl(v.getContext(), (String) v.getTag());
                    }
                });
            }

        }

        @Override
        public void setData(Section<?> section) {
            if (section != null) {
                mTitle.setText(section.label);
                mTitle.setTag(section.link);
            }
        }
    }

    private class CommentViewHolder extends BaseViewHolder<Comment> {
        private RelativeLayout rlContent;
        private FrescoImageView imgIcon;
        private TextView tvTitle;
        private TextView tvDesc;
        private TextView tvUserName;
        private TextView tvTime;
        private FrescoImageView ivUserIcon;

        public CommentViewHolder(View itemView) {
            super(itemView);
            initView(itemView);
        }

        private void initView(View itemView) {
            rlContent = (RelativeLayout) itemView.findViewById(R.id.rl_content);
            imgIcon = (FrescoImageView) itemView.findViewById(R.id.img_icon);
            tvTitle = (TextView) itemView.findViewById(R.id.tv_title);
            tvDesc = (TextView) itemView.findViewById(R.id.tv_desc);
            tvUserName = (TextView) itemView.findViewById(R.id.tv_user_name);
            tvTime = (TextView) itemView.findViewById(R.id.tv_time);
            ivUserIcon = (FrescoImageView) itemView.findViewById(R.id.iv_user_icon);
            rlContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    RouterHelper.toUrl(v.getContext(), (String) v.getTag());
                }
            });
        }

        @Override
        public void setData(final Comment item) {
            if (item != null) {
                imgIcon.loadView(item.img);
                tvDesc.setText(item.comment);
                tvTitle.setText(item.title);
                rlContent.setTag(item.link);
                ivUserIcon.loadView(item.userAvatar, R.drawable.default_bg);
                tvUserName.setText(item.userName);
                tvTime.setText(TimeUtils.format(TimeUtils.TIME_YYYY_MM_DD, item.timestamp * 1000));
            }
        }
    }

    private class RecommendViewHolder extends BaseViewHolder<Notice> {
        private View mRoot;
        private FrescoImageView mImage;
        private TextView mTitle;
        private TextView mDesc;

        public RecommendViewHolder(View v) {
            super(v);
            initView(v);
        }

        private void initView(View v) {
            mRoot = v;
            mImage = v.findViewById(R.id.img_icon);
            mTitle = v.findViewById(R.id.tv_title);
            mDesc = v.findViewById(R.id.tv_desc);
            mRoot.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Object tag = view.getTag();
                    if (tag != null && tag instanceof Notice) {
                        RouterHelper.toUrl(view.getContext(), ((Notice) tag).link);
                    }
                }
            });
        }

        @Override
        public void setData(Notice notice) {
            if (notice != null) {
                mImage.loadView(notice.img);
                mTitle.setText(notice.title);
                mDesc.setText(notice.detail);
                mRoot.setTag(notice);
            }
        }
    }
}
